package com.hxx.widget.richtext

import android.graphics.Typeface
import android.text.Editable
import android.text.Selection
import android.text.Spanned
import android.text.style.*
import androidx.appcompat.widget.AppCompatEditText

class TextUtils {
    companion object {
        const val REPLACE_CHAR = '\u200B'

        /**
         * 应用样式
         */
        fun applySpans(spannable: Editable, spans: List<Any>, start: Int, end: Int) {
            spans.forEach {
                if (it is ParagraphStyle) {

                }
                if (it is CharacterStyle) {

                }
            }
        }

        /**
         * 拆分段落
         */
        fun queryParagraphWidthWrap(spannable: Editable, insertStart: Int, insertEnd: Int,block:(Int,Int,Boolean)->Unit){
            var wrapCount = 0

        }


        /**
         * 对比段落span是否相同
         */
        fun isDifferParagraphSpans(oldSpans:ArrayList<Any>,newSpans:ArrayList<Any>):Boolean{
            if (oldSpans.size != newSpans.size) return false
            val iterator = newSpans.iterator()
            oldSpans.forEach { span ->
                when (span) {
                    is AlignmentSpan -> {
                        for (i in iterator){
                            if (i is AlignmentSpan ) {
                                if (i.alignment != span.alignment){
                                    return false
                                }
                                iterator.remove()
                                break
                            }
                        }
                    }
                    is LeadingMarginSpan.Standard -> {
                        for (i in iterator){
                            if (i is LeadingMarginSpan.Standard ) {
                                if (i.getLeadingMargin(true) != span.getLeadingMargin(true)){
                                    return false
                                }
                                iterator.remove()
                                break
                            }
                        }
                    }
                }
            }
            return true
        }

        /**
         * 对比span是否相同
         */
        fun isDifferSpans(oldSpans:ArrayList<Any>,newSpans:ArrayList<Any>):Boolean{
            if (oldSpans.size != newSpans.size) return false
            val iterator = newSpans.iterator()
            oldSpans.forEach { span ->
                when (span) {
                    is AlignmentSpan -> {
                        for (i in iterator){
                            if (i is AlignmentSpan ) {
                                if (i.alignment != span.alignment){
                                    return false
                                }
                                iterator.remove()
                                break
                            }
                        }
                    }
                    is ForegroundColorSpan -> {
                        for (i in iterator){
                            if (i is ForegroundColorSpan ) {
                                if (i.foregroundColor != span.foregroundColor){
                                    return false
                                }
                                iterator.remove()
                                break
                            }
                        }
                    }
                    is StyleSpan -> {
                        for (i in iterator){
                            if (i is StyleSpan ) {
                                if (i.style != span.style){
                                    return false
                                }
                                iterator.remove()
                                break
                            }
                        }
                    }
                    is RelativeSizeSpan -> {
                        for (i in iterator){
                            if (i is RelativeSizeSpan ) {
                                iterator.remove()
                                break
                            }
                        }
                    }
                    is UnderlineSpan -> {
                        for (i in iterator){
                            if (i is UnderlineSpan ) {
                                iterator.remove()
                                break
                            }
                        }
                    }
                    is StrikethroughSpan -> {
                        for (i in iterator){
                            if (i is StrikethroughSpan ) {
                                iterator.remove()
                                break
                            }
                        }
                    }
                }
            }
            return true
        }
        /**
         * 拆分
         * 1.段落
         * 2.字体样式
         */
        fun splitSpans(spannable: Editable, insertStart: Int, insertEnd: Int,clazz:Class<*>) {
            if (clazz is ParagraphStyle){
                val ps = spannable.getSpans(insertStart,insertEnd,ParagraphStyle::class.java)

            }
        }
        /**
         * 拆分
         */
        fun splitSpans(spannable: Editable, insertStart: Int, insertEnd: Int) {
            val characterSpans =
                spannable.getSpans(insertStart, insertEnd, CharacterStyle::class.java)
            characterSpans.forEach {
                val spanStart = spannable.getSpanStart(it) //span 开始索引
                val spanEnd = spannable.getSpanEnd(it) //span 结束索引
                val headSpan = SpanFactory.copySpan(it)
                val footSpan = it
                spannable.removeSpan(it)
                if (spanStart < insertStart) {
                    spannable.setSpan(
                        headSpan,
                        spanStart,
                        insertStart,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
                if (spanEnd > insertEnd) {
                    spannable.setSpan(
                        footSpan,
                        insertEnd,
                        spanEnd,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
            }

        }

        /***
         * 截取段落
         */
        fun applySpanIndex(
            source: Editable,
            selectionStart: Int,
            selectionEnd: Int,
            apply: (Int, Int) -> Unit
        ) {
            var startIndex = selectionStart
            var endIndex = selectionEnd
            while (true) {
                if (startIndex == 0) break
                startIndex--
                if (source[startIndex] == '\n') {
                    startIndex += 1
                    break
                }
            }

            while (true) {
                if (endIndex == source.length) break
                if (source[endIndex] == '\n') {
                    endIndex++
                    break
                }
                endIndex++
            }
            var rangeStart = startIndex


            for (i in startIndex..endIndex) {
                if (i == endIndex) {
                    apply(rangeStart, i)
                    break
                }
                if (source[i] == '\n') {
                    apply(rangeStart, i + 1)
                    rangeStart = i + 1
                    if (i == endIndex - 1) {
                        break
                    }
                }
            }
        }

        /**
         * 对比span
         */
        fun compareSpan(first: Any, second: Any): Boolean {
            if (first::class.java != second::class.java) {
                return false
            } else {
                when (first) {
                    is ForegroundColorSpan -> {
                        second as ForegroundColorSpan
                        return first.foregroundColor == second.foregroundColor
                    }
                    is StyleSpan -> {
                        second as StyleSpan
                        return first.style == second.style
                    }
                    is StrikethroughSpan -> {
                        return true
                    }
                    is UnderlineSpan -> {
                        return true
                    }
                }
            }
            return false
        }

        /**
         * 获取光标位置的段落位置
         */
        fun getParagraphIndex(s: Editable): IntArray {
            val selectionIndex = Selection.getSelectionStart(s)
            var start = selectionIndex
            var end = selectionIndex
            for (i in selectionIndex - 1 downTo 0) {
                if (i == 0) {
                    start = i
                    break
                }
                if (s[i] == '\n') {
                    start = i + 1
                    break
                }
            }
            for (i in selectionIndex until s.length) {
                if (s[i] == '\n' || i == s.length - 1) {
                    end = i
                    break
                }
            }
            return intArrayOf(start, end)
        }

        /**
         * 将指定范围样式进行修改，分割首尾、并在指定范围内应用样式
         */
        fun applySpans(spannable: Editable, start: Int, count: Int, spans: List<Any>) {
            cutSpansInWord(spannable, start, start + count)
            spans.forEach {
                spannable.setSpan(it, start, start + count, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
        }

        /**
         * 设置为前一个字符相同的样式
         */
        fun followSpans(spannable: Editable, start: Int, count: Int, default: List<Any>) {
            val newChars = CharArray(count)
            spannable.getChars(start, start + count, newChars, 0)
            val newlines = arrayListOf<Int>() //每次遇到换行符需要拆分段落，每个换行符同上一段落一并处理
            for (i in newChars.indices) {
                val c = newChars[i]
                if (c == '\n') {
                    //存在换行符 当前索引+1为要拆分的开始位置
                    newlines.add(i)
                }
            }
            if (newlines.isNotEmpty()) {
                //存在换行符 ，拆分
                newlines.forEach {
                    cutSpansInWord(spannable, it, it + 1, true)
                }

            } else {
                if (start == 0) {
                    //当前字符串输入位置为最开始
                    default.forEach {
                        spannable.setSpan(
                            it,
                            start,
                            start + count,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }
                    return
                }
                val characterSpans =
                    spannable.getSpans(start - 1, start, CharacterStyle::class.java)
                characterSpans.forEach {
                    val spanStart = spannable.getSpanStart(it) //span 开始索引
                    val spanEnd = spannable.getSpanEnd(it) //span 结束索引
                    if (spanStart == spanEnd) {
                        spannable.removeSpan(it)
                    } else if (spanEnd == start) {
                        spannable.setSpan(
                            it,
                            spanStart,
                            spanEnd + count,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }
                }
            }

        }

        /**
         * 将一段文本范围的前后样式分割开
         * keep:是否将指定区域也定义相同样式
         */
        fun cutSpansInWord(
            spannable: Editable,
            insertStart: Int,
            insertEnd: Int,
            keep: Boolean = false
        ) {
            val characterSpans =
                spannable.getSpans(insertStart - 1, insertStart, CharacterStyle::class.java)
            characterSpans.forEach {
                val spanStart = spannable.getSpanStart(it) //span 开始索引
                val spanEnd = spannable.getSpanEnd(it) //span 结束索引
                val headSpan = SpanFactory.copySpan(it)
                val footSpan = it
                spannable.removeSpan(it)
                spannable.setSpan(
                    headSpan,
                    spanStart,
                    insertStart,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                if (spanEnd > insertStart) {
                    spannable.setSpan(
                        footSpan,
                        insertEnd,
                        spanEnd,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
                if (keep) {
                    val keepSpan = SpanFactory.copySpan(it)
                    spannable.setSpan(
                        keepSpan,
                        insertStart,
                        insertStart,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                }
            }
        }


        /**
         * 获取当前光标所在段落
         */
        fun getParagraphPosition(edit: AppCompatEditText): IntArray {
            val selection = Selection.getSelectionStart(edit.text)
            var paragraphStart = 0
            var paragraphEnd = 0
            val lines = edit.text.toString().split("\n")
            var index = 0
            for (element in lines) {
                if (selection <= index + element.length) {
                    paragraphStart = index
                    paragraphEnd = index + element.length
                    break
                } else {
                    index += element.length + 1
                }
            }
            return intArrayOf(paragraphStart, paragraphEnd)
        }

    }

}